(function () {
    if (window.__nicoleCrmproccessDetailInjected__) {
        console.debug('[nicole][crmproccess] 脚本已注入，跳过重复执行');
        return;
    }
    window.__nicoleCrmproccessDetailInjected__ = true;

    const BUTTON_ID = 'nicole-crmproccess-handle-btn';
    const POLL_INTERVAL = 300;
    const MAX_ATTEMPTS = 200; // 最长等待约 60s

    (function logContext() {
        const href = window.location.href;
        let isTopWindow = true;
        try {
            isTopWindow = window.top === window.self;
        } catch (error) {
            isTopWindow = false;
        }
        console.debug('[nicole][crmproccess] 页面上下文信息:', {
            href,
            readyState: document.readyState,
            isTopWindow,
            iframeCount: document.querySelectorAll('iframe').length
        });
    })();

    function toAbsoluteUrl(raw) {
        if (!raw) {
            return null;
        }
        try {
            return new URL(raw, window.location.origin).href;
        } catch (error) {
            console.warn('[nicole][crmproccess] 无法解析 URL:', raw, error);
            return null;
        }
    }

    function getDocumentFrom(root) {
        if (!root) {
            return document;
        }
        if (root.nodeType === 9) {
            return root;
        }
        if (root.ownerDocument) {
            return root.ownerDocument;
        }
        return document;
    }

    function extractTaskIdFromDocument(doc) {
        if (!doc) {
            return null;
        }
        const templateNodes = Array.from(doc.querySelectorAll('script[type="text/template"][id^="fund-out-small-tips-confirm-"]'));
        const taskIds = templateNodes
            .map(node => {
                const match = node.id.match(/fund-out-small-tips-confirm-(\d+)/);
                return match && match[1] ? parseInt(match[1], 10) : null;
            })
            .filter(id => Number.isFinite(id));

        if (taskIds.length > 0) {
            const maxId = Math.max(...taskIds);
            console.debug('[nicole][crmproccess] 解析到任务 ID 列表:', taskIds, '取最大值:', maxId);
            return String(maxId);
        }

        const fallbackMatches = doc.documentElement?.innerHTML?.match(/fund-out-small-tips-confirm-(\d+)/g) || [];
        if (fallbackMatches.length > 0) {
            const ids = fallbackMatches
                .map(item => {
                    const match = item.match(/fund-out-small-tips-confirm-(\d+)/);
                    return match && match[1] ? parseInt(match[1], 10) : null;
                })
                .filter(id => Number.isFinite(id));
            if (ids.length > 0) {
                const maxId = Math.max(...ids);
                console.debug('[nicole][crmproccess] 从 HTML 回退解析任务 ID 列表:', ids, '取最大值:', maxId);
                return String(maxId);
            }
        }

        console.warn('[nicole][crmproccess] 未能解析任务 ID');
        return null;
    }

    function extractTaskIdFromPanel(panel) {
        if (!panel) {
            return null;
        }
        const doc = getDocumentFrom(panel);

        const parseScriptId = (script) => {
            if (!script || !script.id) {
                return null;
            }
            const match = script.id.match(/(\d+)$/);
            if (match && match[1]) {
                return parseInt(match[1], 10);
            }
            return null;
        };

        const collectScriptsFromSiblings = (direction) => {
            const scripts = [];
            let current = panel;
            while (current) {
                current = direction === 'next' ? current.nextSibling : current.previousSibling;
                if (!current) {
                    break;
                }
                if (current.nodeType === 1) {
                    const element = current;
                    if (element.tagName === 'SCRIPT') {
                        scripts.push(element);
                        continue;
                    }
                    if (element.matches && element.matches('.panel')) {
                        break;
                    }
                    if (element.querySelectorAll) {
                        const nestedScripts = Array.from(element.querySelectorAll('script'));
                        if (nestedScripts.length > 0) {
                            scripts.push(...nestedScripts);
                        }
                    }
                    break;
                }
            }
            return scripts;
        };

        const candidateScripts = [
            ...collectScriptsFromSiblings('next'),
            ...collectScriptsFromSiblings('prev')
        ].filter(script => script.type === 'text/template' && script.id);

        const candidateIds = candidateScripts
            .map(parseScriptId)
            .filter(id => Number.isFinite(id));

        if (candidateIds.length > 0) {
            const maxId = Math.max(...candidateIds);
            console.debug('[nicole][crmproccess] 从邻近脚本解析任务 ID 列表:', candidateIds, '取最大值:', maxId);
            return String(maxId);
        }

        console.debug('[nicole][crmproccess] 邻近节点未找到任务 ID 脚本');
        return null;
    }

    function resolveTransferUrl(rootElement, contextPanel) {
        const doc = getDocumentFrom(rootElement);
        const attributeSelectors = [
            '[href*="transferToMyself"]',
            '[data-url*="transferToMyself"]',
            '[data-action*="transferToMyself"]'
        ];

        for (const selector of attributeSelectors) {
            const element = doc.querySelector(selector);
            if (element) {
                const raw = element.getAttribute('href')
                    || element.getAttribute('data-url')
                    || element.getAttribute('data-action');
                const resolved = toAbsoluteUrl(raw);
                if (resolved) {
                    return resolved;
                }
            }
        }

        const panelTaskId = extractTaskIdFromPanel(contextPanel);
        if (panelTaskId) {
            try {
                const origin = (doc.defaultView || window).location.origin;
                return `${origin}/crmproccess/task/${panelTaskId}/transferToMyself`;
            } catch (error) {
                console.warn('[nicole][crmproccess] 使用面板任务 ID 拼接链接时 origin 获取失败，使用当前窗口', error);
                return `${window.location.origin}/crmproccess/task/${panelTaskId}/transferToMyself`;
            }
        }

        const taskId = extractTaskIdFromDocument(doc);
        if (taskId) {
            try {
                const origin = (doc.defaultView || window).location.origin;
                return `${origin}/crmproccess/task/${taskId}/transferToMyself`;
            } catch (error) {
                console.warn('[nicole][crmproccess] 读取任务页面 origin 失败，使用当前窗口', error);
                return `${window.location.origin}/crmproccess/task/${taskId}/transferToMyself`;
            }
        }

        const htmlMatch = doc.documentElement?.innerHTML?.match(/\/crmproccess\/task\/(\d+)\/transferToMyself/);
        if (htmlMatch && htmlMatch[1]) {
            try {
                const origin = (doc.defaultView || window).location.origin;
                return `${origin}/crmproccess/task/${htmlMatch[1]}/transferToMyself`;
            } catch (error) {
                return `${window.location.origin}/crmproccess/task/${htmlMatch[1]}/transferToMyself`;
            }
        }

        const pathMatch = (doc.defaultView || window).location.pathname.match(/\/crmproccess\/task\/pro?ccess\/(\d+)\/detail/);
        if (pathMatch && pathMatch[1]) {
            try {
                const origin = (doc.defaultView || window).location.origin;
                return `${origin}/crmproccess/task/${pathMatch[1]}/transferToMyself`;
            } catch (error) {
                return `${window.location.origin}/crmproccess/task/${pathMatch[1]}/transferToMyself`;
            }
        }

        return null;
    }

    function findTargetPanel() {
        const panels = Array.from(document.querySelectorAll('.panel.panel-danger'));
        console.debug('[nicole][crmproccess] 在当前上下文检测到的 panel-danger 数量:', panels.length);
        if (panels.length === 0) {
            return null;
        }
        const targetPanel = panels[panels.length - 1];
        console.debug('[nicole][crmproccess] 已选取最末尾的 panel-danger 面板');
        return {panel: targetPanel, document};
    }

    function waitForPanel() {
        return new Promise((resolve, reject) => {
            let attempts = 0;

            const check = () => {
                const located = findTargetPanel();
                if (located) {
                    resolve({panel: located.panel, ownerDocument: located.document});
                    return;
                }

                attempts += 1;
                console.debug('[nicole][crmproccess] 第', attempts, '次轮询未命中，等待下次尝试');
                if (attempts >= MAX_ATTEMPTS) {
                    reject(new Error('[nicole][crmproccess] 未能在预期时间内找到目标面板'));
                    return;
                }
                setTimeout(check, POLL_INTERVAL);
            };

            check();
        });
    }

    function createHandleButton(doc) {
        const targetDoc = doc || document;
        const label = targetDoc.createElement('label');
        label.style.cssText = 'float:right;font-weight:500';
        label.id = `${BUTTON_ID}-wrapper`;

        const anchor = targetDoc.createElement('a');
        anchor.id = BUTTON_ID;
        anchor.href = 'javascript:void(0)';
        anchor.textContent = '认领';
        label.appendChild(anchor);
        return {label, anchor};
    }

    function attachButton(panel, ownerDocument) {
        const doc = ownerDocument || document;
        if (doc.getElementById(BUTTON_ID)) {
            console.log('[nicole][crmproccess] 处理按钮已存在，跳过注入');
            return;
        }

        const heading = panel.querySelector('.panel-heading .panel-title') || panel.querySelector('.panel-heading');
        if (!heading) {
            console.warn('[nicole][crmproccess] 未找到面板标题区域，无法插入按钮');
            return;
        }

        const existingHandleLink = heading.querySelector('a');
        if (existingHandleLink && existingHandleLink.textContent && existingHandleLink.textContent.trim().includes('处理')) {
            console.log('[nicole][crmproccess] 已存在处理按钮，跳过注入');
            return;
        }

        const {label, anchor} = createHandleButton(doc);
        heading.appendChild(label);

        anchor.addEventListener('click', async (event) => {
            event.preventDefault();
            const transferUrl = resolveTransferUrl(doc, panel);
            if (!transferUrl) {
                window.alert('暂未找到处理接口地址，请刷新后重试');
                console.warn('[nicole][crmproccess] 未能解析 transferToMyself 地址');
                return;
            }

            const originalText = anchor.textContent;
            anchor.textContent = '认领中...';
            anchor.style.pointerEvents = 'none';

            try {
                const response = await fetch(transferUrl, {
                    method: 'POST',
                    credentials: 'include',
                    headers: {
                        'Accept': 'application/json, text/javascript, */*; q=0.01',
                        'X-Requested-With': 'XMLHttpRequest'
                    }
                });

                if (!response.ok) {
                    throw new Error(`HTTP ${response.status}`);
                }

                const data = await response.json();
                if (data && data.success) {
                    window.location.reload();
                } else {
                    const errorMsg = data && data.msg ? data.msg : '接口返回失败';
                    throw new Error(errorMsg);
                }
            } catch (error) {
                console.error('[nicole][crmproccess] 转交任务失败', error);
                window.alert(error && error.message ? error.message : '处理失败，请稍后再试');
                anchor.textContent = originalText;
                anchor.style.pointerEvents = '';
            }
        });

        console.log('[nicole][crmproccess] 认领按钮已注入');
    }

    waitForPanel()
        .then(({panel, ownerDocument}) => attachButton(panel, ownerDocument))
        .catch(error => console.warn(error.message));
})();
